        TITL DAI FIRMWARE 1EC00-1EE0A  V1.0  Rev.1
        ORG   :EC00
*
*
*
************************
* FIXED MULTIPLICATION *
************************
*
* Multiplies a mantissa in registers C,D,E with
* the mantissa of a number in the MACC. The result
* is in B,C,D,E (binary point left of B).
*
* Used for multiplication of mantissa's in a
* FPT multiplication.
*
* Exit: AFHL corrupted.
*
MULX    MOV   A,C       )
        STA   :00DD     ) Mantissa from CDE into
        MOV   H,D       )   00DD, 00DC, 00DB
        MOV   L,E       )
        SHLD  :00DB     )
        XRA   A
        MOV   D,A       )
        MOV   C,A       ) Clear ABCD
        MOV   B,A       )
        LDA   :00D8     Get lobyte MACC mantissa
        CALL  :EC1C     Multiply
        LDA   :00D7     Get next byte MACC mantissa
        CALL  :EC1C     Multiply
        LDA   :00D6     Get hibyte MACC mantissa
 REM
* Prepare multiplication:
 REM
L1E203  MOV   L,D
        MOV   E,C
        MOV   D,B
        MOV   B,A       Byte from MACC in B
        XRA   A
        MOV   C,A
        SUB   B
        JC    :EC29     Then multiply
        MOV   C,D
        MOV   D,E
        RET
 REM
* Multiply (product in BDCE):
 REM
L1E204  MOV   A,L
        ADC   A
        RZ              Abort if 2*L+CY=0
        MOV   L,A       Else update L
        CALL  :EB48     Shift BCDE 1 bit left
        JNC   :EC29     Again if no overflow
        LDA   :00DB
        ADD   E
        MOV   E,A       E=E+(00DB)
        LDA   :00DC
        ADC   D
        MOV   D,A       D=D+(00DC)+CY
        LDA   :00DD
        ADC   C
        MOV   C,A       C=C+(00DD)+CY
        JNC   :EC29     Again if no overflow
        INR   B         If overflow: B=B+1
        ORA   A         Clear CY
        JMP   :EC29     Again
*
******************
* FIXED DIVISION *
******************
*
* Divides a mantissa in registers C,D,E by the
* mantissa of the number in the MACC. The result
* is in B,C,D and the msb of E. The remainder is
* in the rest of E and in HL.
*
* Used to divide mantissa's in a FPT division.
*
* Exit: AF corrupted.
*       CY=1: Overflow in adjusting exponents.
*       CY=0: O.K.
*
DIVX    LXI   H,:00D8   Addr lobyte MACC
        MOV   A,M       )
        SUB   E         )
        MOV   M,A       )
        DCX   H         ) Mantissa MACC =
        MOV   A,M       ) CDE - mantissa MACC
        SBB   D         )
        MOV   M,A       )
        DCX   H         )
        MOV   A,M       )
        SBB   C         )
        MOV   M,A       )
        LXI   H,:00DD   Addr save area
        STC
        MOV   A,C       )
        RAR             )
        MOV   M,A       )
        DCX   H         )
        MOV   A,D       ) 00DD,00DC,00DB =
        RAR             ) CDE SHR 1 with msb C=1
        MOV   M,A       )
        DCX   H         )
        MOV   A,E       )
        RAR             )
        MOV   M,A       )
        DCX   H
        MVI   B,:00
        MOV   A,B       )
        RAR             )
        MOV   M,A       ) 00DA =00 or 80, depending
 REM ) on result RAR
        LXI   H,:00D6
        MOV   A,M       )
        INX   H         ) Get mantissa MACC in ADE
        MOV   D,M       )
        INX   H         )
        MOV   E,M       )
        ORA   A
        JM    :ECC4     Jump if normalised
        CALL  :EBD9     Incr FPT exponent
        RC              Abort if overflow
        MOV   L,E       )
        MOV   H,D       ) Remainder in EHL
        MOV   E,A       )
        MVI   D,:01
        MOV   C,B
L1E206  PUSH  B
        MOV   B,H
        MOV   C,L
        LXI   H,:00DA
        XRA   A
        SUB   M
        INX   H
        MOV   A,C
        SBB   M
        MOV   C,A
        INX   H
        MOV   A,B
        SBB   M
        MOV   B,A
        INX   H
        MOV   A,E
        SBB   M
        MOV   E,A
        MOV   L,C
        MOV   H,B
        POP   B
L1E207  LDA   :00DA
        RLC
        MOV   A,B
        RAL
        CMC
        RNC
        RAR
        MOV   A,L
        RAL
        MOV   L,A
        MOV   A,H
        RAL
        MOV   H,A
        CALL  :EB48     Shift BCDE left 1 bit
        MOV   A,D
        RRC
        JC    :EC83
L1E208  PUSH  B
        MOV   B,H
        MOV   C,L
        LHLD  :00DB
        DAD   B
        LDA   :00DD
        ADC   E
        MOV   E,A
        POP   B
        LDA   :00DA
        JMP   :EC9D
L1E209  MOV   L,E
        MOV   H,D
        MOV   E,A
        MOV   D,B
        MOV   C,B
        JMP   :ECB1
*
*
***********************************
* AMD: ISSUE COMMAND TO MATH.CHIP *
***********************************
*
* Entry: HL points to command.
* Exit:  HL updated, A corrupted, BCDEF preserved.
*
MPT15   MOV   A,M       Get command
        INX   H
        STA   :FB02     Issue cmd to math.chip
        RET
*
******************************
* AMD: TURN OFF ERROR STATUS *
******************************
*
* Exit: All registers preserved.
*
MPT16   PUSH  PSW
        XRA   A
        STA   :FB02     Cmd math.chip = 0
        POP   PSW
        RET
*
****************************************
* AMD: LOAD 16-BIT DATA INTO MATH.CHIP *
****************************************
*
* Entry: 1st byte in A, 2nd on stack.
*
MPT17   STA   :FB00     Load 1st byte in math.chip
        POP   PSW
        STA   :FB00     Load data in math.chip
        RET
*
**************************
* part of 'IAND' (1E32C) *
**************************
*
L1E213  CALL  :E38C     Copy MACC into EBCA
        CALL  :E335     Run IAND
        JMP   :E385     Copy ABCD into MACC
*
*************************
* part of 'IOR' (1E345) *
*************************
*
L1E214  CALL  :E38C     Copy MACC into EBCA
        CALL  :E34C     Run IOR
        JMP   :E385     Copy ABCD into MACC
*
**************************
* part of 'IXOR' (1E35C) *
**************************
*
L1E215  CALL  :E38C     Copy MACC into EBCA
        CALL  :E363     Run IXOR
        JMP   :E385     Copy ABCD into MACC
*
*****************************************
* COPY MACC INTO REGISTERS A,B,C,D: CMA *
*****************************************
*
* Part of 1E373.
*
L1E216  CALL  :E133     Copy MACC into ABCD
        CMA             Compl exponent byte
        RET
*
************************************
* COPY MACC INTO REGISTERS E,B,C,A *
************************************
*
* Part of 1E38C.
*
L1E217  CALL  :E133     Copy MACC into ABCD
IGP10   MOV   E,A       Exp in E
        JMP   :E38F     Copy BCDE into EBCA
*
************************************
* COPY MACC INTO REGISTERS B,C,D,E *
************************************
*
* Part of SHR (1E398) and SHL (1E3A5).
* Tests if the value of a INT operand in memory is
* bigger than 32 (nr of bits for a mantissa).
* If not, the contents of the MACC is copied
* into the registers BCDE. If the number is too
* big, the registers BCDE are cleared.
*
* Entry: HL points to INT operand in memory.
*
L1E219  CALL  :E3B2     Test if operand > 31; if
 REM true: clear ABCDE
        CZ    :E3D6     If OK: nr in A, contents
 REM MACC into BCDE
        RET
*
*********************************************
* COPY CONTENTS MACC INTO REGISTERS B,C,D,E *
*********************************************
*
* Entry L1E220: Not used.
* Entry GBC10 : Copy ABCD into BCDE.
*
L1E220  PUSH  PSW
        CALL  :E56F     Copy MACC into ABCD
*
GBC10   MOV   E,D       )
        MOV   D,C       ) Copy ABCD into BCDE
        MOV   C,B       )
        MOV   B,A       )
        POP   PSW
        RET
*
*************
* AMD: IAND *
*************
*
* MTOS = MTOS IAND MEM.
*
* Entry: HL points to operand in memory.
* Exit:  All registers preserved.
*
ZIAND   PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        CALL  :ED4F     Copy MTOS into EBCA
        CALL  :E335     Run IAND
        JMP   :ED3D     Result into MTOS
*
************
* AMD: IOR *
************
*
* MTOS = MTOS IOR MEM.
*
* Entry: HL points to operand in memory.
* Exit:  All registers preserved.
*
ZIOR    PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        CALL  :ED4F     Copy MTOS into EBCA
        CALL  :E34C     Run IOR
        JMP   :ED3D     Result into MTOS
*
*************
* AMD: IXOR *
*************
*
* MTOS = MTOS IXOR MEM.
*
* Entry: HL points to operand in memory.
* Exit:  All registers preserved.
*
ZIXOR   PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        CALL  :ED4F     Copy MTOS into EBCA
        CALL  :E363     Run IXOR; result in ABCD
ZORT1   CALL  :E55F     Copy ABCD into MTOS
        JMP   :C14D     Popall, ret
*
*************
* AMD: INOT *
*************
*
* MTOS = INOT (MTOS).
*
* Exit: All registers preserved.
*
* REMARK: Wrong routine: MTOS is made -MTOS,
*         and then 1 is added. So result is
*         INOT (MTOS)+2.
*         Correct would be: Add -1.
*
ZINOT   CALL  :E522     Change sign MTOS (INT)
        PUSH  H
        LXI   H,:C420   Addr INT (1)
        CALL  :E4F4     MTOS = - MTOS + 1
        POP   H
        RET
*
*****************************************
* AMD: COPY MTOS INTO REGISTERS E,B,C,A *
*****************************************
*
ZIGTP   CALL  :E56F     Copy MTOS into ABCD
        JMP   :ED04     Copy ABCD into EBCA
*
************
* AMD: SHR *
************
*
* Shifts MTOS right MEM positions.
*
* Entry: HL points to INT number in memory.
* Exit:  All registers preserved.
*
ZSHR    PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        CALL  :E3B2     Check value of MEM. Value in
 REM A. Clear ABCDE if too big
        CZ    :ED7C     Else: Copy MTOS in BCDE
        CALL  :EB55     Shift BCDE right A positions
ZRREG   MOV   A,B       )
        MOV   B,C       )
        MOV   C,D       ) Copy BCDE into ABCD
        MOV   D,E       )
        CALL  :E55F     Copy ABCD into MTOS
        JMP   :C14D     Popall, ret
*
************
* AMD: SHL *
************
*
* Shifts MTOS left MEM positions.
*
* Entry: HL points to INT number in memory.
* Exit:  All registers preserved.
*
ZSHL    PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        CALL  :E3B2     Test value of MEM. Value in
 REM A. Clear ABCDE if too big
        CZ    :ED7C     If OK: Copy MTOS into BCDE
        CALL  :EB39     Shift BCDE left A positions
        JMP   :ED62     Copy BCDE into MTOS
*
*****************************************
* AMD: COPY MTOS INTO REGISTERS B,C,D,E *
*****************************************
*
* Exit: AHL preserved.
*
ZGBCDE  PUSH  PSW
        CALL  :E56F     Copy MTOS into ABCD
        JMP   :ED13     Copy ABCD into BCDE
*
*
***********************************************
* CHECK IF CONTENTS REGISTERS B,C,D,E IS ZERO *
***********************************************
*
* Exit: Z=1: Contents BCDE is zero.
*       BCDEHL preserved.
*
L1E232  MOV   A,B
        ORA   C
        ORA   D
        ORA   E
        RET
*
******************************************
* EVT. NEGATE CONTENTS REGISTERS B,C,D,E *
******************************************
*
* If S=1: Contents BCDE is negated. Overflow
*         exit if negation not possible.
* On exit, flags are set on contents entry A.
*
L1E233  PUSH  PSW
        CM    :E3C9     Evt negate BCDE
        POP   PSW
        ORA   A
        RET
*
****************
* SIGN COMPARE *
****************
*
* Entry: HL: Points to divisor.
* Exit:  B:  Exponent MACC.
*        F:  Set on XOR of exp bytes MACC and MEM.
*            S=1 if difference in sign.
*
L1E234  LDA   :00D5     Get exp byte MACC
        MOV   B,A       in B
        XRA   M         XOR with exp byte MEM
        RET
*
**********************************
* AMD: GET STATUS BITS MATH.CHIP *
**********************************
*
* Exit: A: Status.
*       FBCDEHL preserved.
*
M4STAT  CALL  :E52D     Operate immediate
        DATA  :37       Push MTOS
        CALL  :E52D     Operate immediate
        DATA  :38       Pop MTOS
        LDA   :FB02     Get status math.chip
        RET
*
**************
* AMD: POWER *
**************
*
* MTOS = MTOS ^ MEM.
*
* Entry: HL points to power in memory.
* Exit:  AF corrupted, BCDEHL preserved.
*
ZPWR    CALL  :ED95     Get status math.chip
        ANI   :20       MTOS empty ?
        RNZ             Abort if not
        JMP   :E4AC     Run PWR routine
*
****************
* FPT ADDITION *
****************
*
* For FPT values: MACC = MACC + MEM.
*
* Entry: HL points to FPT number in memory.
* Exit:  All registers preserved.
*
XFADD   PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        CALL  :EA72     MACC = MACC + MEM
        JMP   :C14D     Popall, ret
*
*******************
* FPT SUBTRACTION *
*******************
*
* For FPT values: MACC = MACC - MEM.
*
* Entry: HL points to FPT number in memory.
* Exit:  All registers preserved.
*
XFSUB   PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        CALL  :EA6D     MACC = MACC - MEM
        JMP   :C14D     Popall, ret
*
        DATA  :FF
        DATA  :FF
*
***************************************
* SAVEA: PREPARE SAVING STRING ARRAYS *
***************************************
*
* Reserves space in free RAM for a string, composed
* from all string elements of a string array.
* The array elements are moved into this area.
* If not sufficient free RAM available, 'OUT OF
* MEMORY' error occurs.
*
* Entry: DE: Length array to be saved.
*        HL: Pointer to array.
* Exit:  DE: Length of block in free RAM.
*        HL: Startaddress block in free RAM.
*        AF corrupted, BC preserved.
*
MSA     PUSH  B
        MOV   B,D       ) Length array in BC
        MOV   C,E       )
        XCHG            Varptr in DE
        LHLD  :02A3     Get startaddr free RAM space
        PUSH  H         and save it on stack
        XCHG            and in DE; HL is array pntr
        MOV   A,B       )
        CALL  :EDFD     ) Save length array in 1st
        MOV   A,C       ) location free RAM
        CALL  :EDFD     )
L1E240  MOV   A,B
        ORA   C
        JZ    :EDE5     Abort if ready
        MOV   A,M
        INX   H
        PUSH  H         Addr array pntr on stack
        MOV   H,M       ) Addr string element in HL
        MOV   L,A       )
        CALL  :EDED     Store element in free RAM
        POP   H         Get array pntr back
        INX   H         Pnts to next element
        DCX   B         ) Decr length still to be
        DCX   B         ) done
        JMP   :EDD1     Continu
 REM
* If ready:
 REM
L1E241  POP   H         Get startaddr new string
        XCHG            in DE; HL is end used area
        CALL  :DE1A     Calc length of string
        XCHG            in DE
        POP   B
        RET
*
* COPY STRING ELEMENT INTO FREE RAM:
*
L1E242  PUSH  B
        MOV   B,M       Get length of string in B
L1E243  MOV   A,M       Byte in A
        INX   H         Pnts to next byte
        CALL  :EDFD     Copy byte into free RAM
        MOV   A,B       )
        SUI   :01       ) Update length
        MOV   B,A       )
        JNC   :EDEF     Next byte if not ready
        POP   B
        RET
*
* STORE STRINGDATA IN FREE RAM SPACE:
*
* Moves 1 byte of a string array element into the
* free RAM space and checks for 'OUT OF MEMORY'.
*
* Entry: DE: Points to 1st free address in RAM.
*        A:  Byte to be moved.
* Exit:  DE updated, BCHL preserved.
*
L1E244  STAX  D         Store byte in free RAM
        INX   D         Update RAM pntr
        PUSH  H
        LHLD  :02A5     Get addr bottom screen RAM
        CALL  :DE14     End free RAM reached ?
        JC    :DA10     Then run error 'OUT OF
 REM MEMORY'
        POP   H
        RET
*
*
*
        END
